package com.cskaoyan.wordmemorize.service.impl;

import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
import com.cskaoyan.wordmemorize.common.annotation.OperateLog;
import com.cskaoyan.wordmemorize.common.constant.ResultCodeEnum;
import com.cskaoyan.wordmemorize.common.exception.BusinessException;
import com.cskaoyan.wordmemorize.service.FileService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.UUID;

/**
 * 文件上传服务实现类
 */
@SuppressWarnings("LoggingSimilarMessage")
@Service
@Slf4j
public class FileServiceImpl implements FileService {

    @Value("${ali.oss.endpoint}")
    private String endpoint;

    @Value("${ali.oss.accessKeyId}")
    private String accessKeyId;

    @Value("${ali.oss.accessKeySecret}")
    private String accessKeySecret;

    @Value("${ali.oss.bucketName}")
    private String bucketName;


    /**
     * 上传文件到OSS
     *
     * @param file      文件
     * @param directory 存储目录，例如：avatar, audio
     * @return 文件访问URL
     * @throws IOException IO异常
     */
    @Override
    @OperateLog(dateType = "文件", operateType = 1)
    public String uploadFile(MultipartFile file, String directory) throws IOException {
        if (file == null || file.isEmpty()) {
            throw new BusinessException("上传文件不能为空", ResultCodeEnum.PARAM_ERROR.getCode());
        }

        // 构造桶中的对象名称
        String originalFilename = file.getOriginalFilename();
        String extension = null;
        if (originalFilename != null) {
            extension = originalFilename.substring(originalFilename.lastIndexOf("."));
        }
        String objectName = directory + "/" + UUID.randomUUID() + extension;

        // 创建 OSSClient 实例
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
        StringBuilder stringBuilder = new StringBuilder();

        try {
            // 向桶中放入指定名称的对象
            ossClient.putObject(bucketName, objectName, file.getInputStream());

            // 文件访问路径规则 https://BucketName.Endpoint/ObjectName
            stringBuilder.append("https://")
                    .append(bucketName)
                    .append(".")
                    .append(endpoint)
                    .append("/")
                    .append(objectName);

            log.info("文件上传成功，URL: {}", stringBuilder);
            return stringBuilder.toString();
        } catch (OSSException oe) {
            log.error("阿里OSS异常，Error Message: {}", oe.getErrorMessage());
            throw new BusinessException("文件上传失败: " + oe.getErrorMessage(), ResultCodeEnum.FAIL.getCode());
        } catch (ClientException ce) {
            log.error("阿里OSS Client异常，Error Message: {}", ce.getMessage());
            throw new BusinessException("文件上传失败: " + ce.getMessage(), ResultCodeEnum.FAIL.getCode());
        } finally {
            if (!ObjectUtils.isEmpty(ossClient)) {
                ossClient.shutdown();
            }
        }
    }


    /**
     * 从URL中删除文件
     *
     * @param fileUrl 文件URL
     */
    @Override
    @OperateLog(dateType = "文件", operateType = 3)
    public void deleteFile(String fileUrl) {
        if (fileUrl == null || fileUrl.isEmpty()) {
            return;
        }

        String objectName = getObjectNameFromUrl(fileUrl);
        if (objectName.isEmpty()) {
            return;
        }

        // 创建 OSSClient 实例
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);

        try {
            // 删除桶中指定对象
            ossClient.deleteObject(bucketName, objectName);
            log.info("文件删除成功，objectName: {}", objectName);
        } catch (OSSException oe) {
            log.error("阿里OSS异常，Error Message: {}", oe.getErrorMessage());
        } catch (ClientException ce) {
            log.error("阿里OSS Client异常，Error Message: {}", ce.getMessage());
        } finally {
            if (!ObjectUtils.isEmpty(ossClient)) {
                ossClient.shutdown();
            }
        }
    }


    /**
     * 从URL中获取文件名称
     *
     * @param fileUrl 文件URL
     * @return 文件名称
     */
    @Override
    public String getObjectNameFromUrl(String fileUrl) {
        if (fileUrl == null || fileUrl.isEmpty()) {
            return "";
        }

        // 解析URL获取对象名称
        // 示例URL: https://bucketName.endpoint/objectName
        String prefix = "https://" + bucketName + "." + endpoint + "/";
        if (fileUrl.startsWith(prefix)) {
            return fileUrl.substring(prefix.length());
        }
        return "";
    }
}
